<template>
<div class="about">
  <!-- 自动读取count对象中的value属性 -->
  <h2>count: {{count}}</h2>
  <h2>msg: {{state.msg}}</h2>
  <h2>user: {{state.user}}</h2>
  <h2>numbers: {{state.numbers}}</h2>
  <button @click="update">更新</button>
</div>
</template>

<script lang="ts">
import {
  ref,
  reactive,
  watch,
} from 'vue'

interface IState {
  msg: string
  user: {
    name: string
    age: number
    sex?: string
  }
  numbers: number[]
}

export default {
  name: 'About',

  // 向模板提供响应式数据和函数
  setup () {

    const count = ref(1)
  
    // 创建一个reactive响应式对象
    // 本质是一个代理对象proxy
    const state = reactive<IState>({
      msg: 'abc',
      user: {
        name: 'tom',
        age: 12
      },
      numbers: [1, 3, 5]
    })
    // console.log(state)

    // 用于更新响应式数据的函数
    const update = () => {
      // count.value += 1

      state.msg += '--'
      // state.user.name += '++'
      // 直接添加一个新属性  ==> vue2中不可以   ==> vue3中可以
      // state.user.sex = '男'
      // 直接通过下标来更新/添加数组元素 ==> vue2中不可以   ==> vue3中可以
      // state.numbers[3] = 4

    }

    // 监视ref数据
    watch(count, (newVal, oldVal) => {
      console.log('watch count', newVal, oldVal)
    })

    // 监视reactive数据
    // 被监视的必须是一个响应式数据, 而不能是一个非响应式数据
    // state.msg的值是一个字符串, 是非响应式的, 不可以直接监视 ==> 可以包装为一个函数
    // watch(state.msg, (newVal, oldVal) => {  // error
    watch(() => state.msg, (newVal, oldVal) => {
      console.log('watch state.msg', newVal, oldVal)
    })

    // 监视多个数据
    watch([count, () => state.msg], (newVals, oldVals) => {
      console.log('watch count & msg', newVals, oldVals)
    }, {immediate: true, deep: true})  // 可以配置立即执行和深度监视



    return { // 对象中的所有属性和方法, 模板可以直接使用
      count,
      state,
      update
    }
  }
}
</script>
